#include "createuserdialog.h"
#include "ui_createuserdialog.h"
#include <QRegularExpression>
#include <limits>
#include <QTcpSocket>
#include <QHostAddress>
#include <QJsonDocument>
#include <QJsonObject>
#include <QByteArray>
#include <QMessageBox>

CreateUserDialog::CreateUserDialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::CreateUserDialog)
{
    ui->setupUi(this);
    tcpSocket=new QTcpSocket(this);
    tcpSocket->connectToHost(QHostAddress("43.155.134.125"),8888);
    connect(tcpSocket,&QTcpSocket::readyRead,this,&CreateUserDialog::do_readyRead);
}

CreateUserDialog::~CreateUserDialog()
{
    delete ui;
}

void CreateUserDialog::on_editPSWD_textChanged(const QString &arg1)
{
    // 清理输入并初始化错误信息
    pswd = ui->editPSWD->text().trimmed();  // 去除前后空格
    strPSWD.clear();

    // 1. 基础校验：空值和长度
    const int MIN_LENGTH = 8;
    const int MAX_LENGTH = 20;

    if (pswd.isEmpty()) {
        strPSWD = "密码不能为空";
        ui->labelPSWD->setText(strPSWD);
        boolPSWD=false;
        return;
    } else if (pswd.length() < MIN_LENGTH) {
        strPSWD = QString("密码至少需要 %1 位").arg(MIN_LENGTH);
        ui->labelPSWD->setText(strPSWD);
        boolPSWD=false;
        return;
    } else if (pswd.length() > MAX_LENGTH) {
        strPSWD = QString("密码不能超过 %1 位").arg(MAX_LENGTH);
        ui->labelPSWD->setText(strPSWD);
        boolPSWD=false;
        return;
    }

    // 2. 复杂度校验：必须包含大小写字母、数字、特殊符号
    // if (strPSWD.isEmpty()) {
    //     QRegularExpression regex(
    //         "^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d)(?=.*[!@#$%^&*()_+\\-=\\[\\]{};':\"\\\\|,.<>\\/?]).+$"
    //         );

    //     if (!regex.match(pswd).hasMatch()) {
    //         strPSWD = "必须包含大小写字母、数字和特殊符号";
    //     }
    // }

    // 3. 防御性过滤：禁止包含SQL元字符（即使参数化查询也建议过滤）
    if (strPSWD.isEmpty() && pswd.contains(QRegularExpression("[\"'\\\\;]"))) {
        strPSWD = "密码包含危险字符（如引号、分号）";
        ui->labelPSWD->setText(strPSWD);
        boolPSWD=false;
        return;
    }
    // 4. 显示校验结果
    strPSWD="密码符合条件";
    ui->labelPSWD->setText(strPSWD);
    boolPSWD=true;

    // 5. 安全存储：实际存储时应使用加密哈希（如bcrypt）
    // 示例：QCryptographicHash::hash(pswd.toUtf8(), QCryptographicHash::Blake2b_256);

    if(boolID&&boolName&&boolPSWD){
        ui->btnCreate->setEnabled(true);
    }else{
        ui->btnCreate->setEnabled(false);
    }
}


void CreateUserDialog::on_editName_textChanged(const QString &arg1)
{
    // 清理输入并初始化错误信息
    name = ui->editName->text().trimmed();  // 去除前后空格
    strName.clear();

    // 1. 检查是否为空
    if (name.isEmpty()) {
        strName = "名称不能为空";
        ui->labelName->setText(strName);
        boolName=false;
        return;
    }

    // 2. 检查长度限制（假设数据库字段为 VARCHAR(50)）
    const int MAX_NAME_LENGTH = 50;
    if (name.length() > MAX_NAME_LENGTH) {
        strName = QString("名称过长（最多 %1 字符）").arg(MAX_NAME_LENGTH);
        ui->labelName->setText(strName);
        boolName=false;
        return;
    }

    // 3. 正则表达式验证合法字符
    // 允许：中文、字母、数字、空格、下划线、短横线、点号
    QRegularExpression regex(
        "^[\\p{L}0-9 \\-_·.]+$",  // \p{L} 匹配所有语言的字母（包括中文）
        QRegularExpression::UseUnicodePropertiesOption
        );

    if (!regex.match(name).hasMatch()) {
        strName = "名称包含非法字符（仅允许中文、字母、数字、-_ .）";
        ui->labelName->setText(strName);
        boolName=false;
        return;
    }

    // 4. 防止SQL注入的二次处理（实际应使用参数化查询！）
    // name = name.replace("'", "''");  // 如果必须拼接SQL，转义单引号（不推荐）

    // 验证通过，清除错误信息
    strName="名称符合条件";
    ui->labelName->setText("符合条件");
    boolName=true;

    if(boolID&&boolName&&boolPSWD){
        ui->btnCreate->setEnabled(true);
    }else{
        ui->btnCreate->setEnabled(false);
    }
}



bool CreateUserDialog::isIdValidInt(const QString &id) {
    strID.clear(); // 清空错误信息

    // 1. 检查是否为空
    if (id.isEmpty()) {
        strID = "ID不能为空";
        return false;
    }

    // 2. 正则验证：必须为纯数字且不允许前导零（除非是0）
    QRegularExpression regex("^[1-9]\\d*$"); // 匹配正整数（不允许负号、前导零）
    if (!regex.match(id).hasMatch()) {
        strID = "ID必须为纯数字且不能以0开头";
        return false;
    }

    // 3. 转换为数值并检查范围
    bool ok;
    qlonglong num = id.toLongLong(&ok);
    if (!ok) {
        strID = "数字格式无效";
        return false;
    }

    // 4. 检查是否为有效正整数（1 ~ INT_MAX）
    if (num < 1 || num > std::numeric_limits<int>::max()) {
        strID = QString("数字必须在 1 到 %1 之间").arg(std::numeric_limits<int>::max());
        return false;
    }

    return true;
}

void CreateUserDialog::on_editUser_textChanged(const QString &arg1)
{
    ID = ui->editUser->text().trimmed(); // 去除前后空格
    bool ok = isIdValidInt(ID);
    boolID=ok;

    if(ok){//发给服务器是否被注册过
        //向服务器查询,id是否重复
        QJsonObject jsonObject;
        jsonObject["type"]="IDIfExist";
        jsonObject["ID"]=ID;
        tcpSocket->write(QJsonDocument(jsonObject).toJson());
    }else{
        ui->labelID->setText(strID); // 直接显示错误信息
    }
}

void CreateUserDialog::do_readyRead()
{
    QJsonDocument doc=QJsonDocument::fromJson(tcpSocket->readAll());
    if(!doc.isNull()&&doc.isObject()){//有效josn
        QJsonObject jsonRoot=doc.object();
        if(!jsonRoot.isEmpty()&&jsonRoot.contains("type")){
            QString strType=jsonRoot["type"].toString();
            if(strType=="IDIfExist"){
                QString str=jsonRoot["exist"].toString();
                if(str=="true"){
                    ui->labelID->setText("该账号已存在"); // 直接显示错误信息
                    boolID=true;
                }else{
                    ui->labelID->setText("符合条件");
                }
            }else if(strType=="addUser"){
                if(jsonRoot["background"].toString()=="createOk"){
                    QMessageBox::information(this,"创建结果","账号创建成功");
                    this->accept();
                }else{
                    QMessageBox::information(this,"创建结果","账号创建失败");
                }
            }
        }
    }
}


void CreateUserDialog::on_btnCreate_clicked()
{
    QJsonObject jsonObject;
    jsonObject["type"]="addUser";
    jsonObject["ID"]=ID;
    jsonObject["username"]=name;
    jsonObject["password"]=pswd;
    tcpSocket->write(QJsonDocument(jsonObject).toJson());
}

